package smallfrench.moteur.lexer;

/**
 * Lecteur d’une chaine de caractères.<br>
 * Mémorise les numéros de lignes et de colonnes pour créer des objets
 * {@link Position}.
 * @author antoine1023
 *
 */
public class LecteurChaine {

	private char[] string;

	/** Position dans la chaine */
	private int position;

	/** Numéro de ligne. */
	private int ligne;

	/** Numéro de colonne, peut être -1. */
	private int colonne;

	/** Fin de fichier */
	private boolean eof;

	// -----------------------------------------------------

	public LecteurChaine(String r) {
		string = r.toCharArray();
		eof = (r.length() == 0);
		position = 0;
		ligne = 1;
		colonne = 0;
	}

	// -----------------------------------------------------

	public boolean isEof() {
		return eof;
	}

	/**
	 * Avance d’un caractère
	 * @return le caractère lu.
	 */
	public char suivant() {
		char c = string[position];
		if (c == '\n') {
			ligne++;
			colonne = 0;
		} else {
			colonne++;
		}
		position++;
		if (position >= string.length) {
			eof = true;
		}
		return c;
	}

	/**
	 * Recule d’un caractère.
	 */
	public void precedent() {
		eof = false;
		position--;
		char c = string[position];
		if (c == '\n') {
			ligne--;
			// On ne sait pas quelle est la taille de la ligne avant le \n
			colonne = -1;
		} else {
			colonne--;
		}
	}

	/**
	 * Recule de n caractères.
	 * @param n
	 */
	public void precedent(int n) {
		for (int i = 0; i < n; i++) {
			precedent();
		}
	}

	public int getNumLigne() {
		return ligne;
	}

	public Position getPosition() {
		return new Position(ligne, colonne, position);
	}

	public void goTo(int newPosition) {
		try {
			while (position < newPosition && !eof) {
				suivant();
			}

			while (position > newPosition && position > 0) {
				precedent();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

}
